using System;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Collections;
using System.IO;
using System.Windows.Forms;
using System.Xml;

using OR.Reuse.Persistence;

using OR.Lazarus.Business;
using OR.Lazarus.Config;
using OR.Lazarus.Library;
using OR.Lazarus.Utility;

using Config	= OR.Lazarus.Business.Entities.Config;
using Compiled = OR.Lazarus.Library.DataTier.Compiled;
using Source   = OR.Lazarus.Library.DataTier.Source;

using OR.Lazarus.Windows;
using OR.Lazarus.Library.DataTier;

namespace OR.Lazarus.Presentation
{
	/// <summary>
	/// Summary description for Form1.
	/// </summary>
	public class Form1 : System.Windows.Forms.Form, ILogViewer
	{
		private ICompilerEngine mCompiler;
		private ToolStripContainer toolStripContainer1;
		private SplitContainer splitContainer1;
		private StatusStrip statusStrip1;
		private ToolStripStatusLabel lblGenerationProgress;
		private ToolStripProgressBar barGenerationProgress;
		private ToolStripStatusLabel lblStatus;
		private ToolStrip toolStrip1;
		private ToolStripButton btnCompile;
		private ToolStripSeparator toolStripSeparator1;
		private ToolStripButton btnSaveLog;
		private MenuStrip menuStrip1;
		private ToolStripMenuItem fileToolStripMenuItem;
		private ToolStripMenuItem settingsToolStripMenuItem;
		private ToolStripSeparator toolStripSeparator2;
		private ToolStripMenuItem exitToolStripMenuItem;
		private ToolStripMenuItem compilerToolStripMenuItem;
		private ToolStripMenuItem goToolStripMenuItem;
		private ToolStripSeparator toolStripSeparator3;
        private ToolStripMenuItem saveLogToolStripMenuItem;
		private OR.Lazarus.Windows.UserControls.UCCompilerFiles m_ucCompilerFiles;
		private CompilerLogViewer mLog;
		private IContainer components;

		public Form1()
		{
			//
			// Required for Windows Form Designer support
			//
			InitializeComponent();

			this.OnInit();
		}

		/// <summary>
		/// Clean up any resources being used.
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if (components != null) 
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		#region Windows Form Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
            OR.Lazarus.Business.Entities.Log.LogDetail logDetail1 = new OR.Lazarus.Business.Entities.Log.LogDetail();
            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1));
            this.toolStripContainer1 = new System.Windows.Forms.ToolStripContainer();
            this.statusStrip1 = new System.Windows.Forms.StatusStrip();
            this.lblGenerationProgress = new System.Windows.Forms.ToolStripStatusLabel();
            this.barGenerationProgress = new System.Windows.Forms.ToolStripProgressBar();
            this.lblStatus = new System.Windows.Forms.ToolStripStatusLabel();
            this.splitContainer1 = new System.Windows.Forms.SplitContainer();
            this.m_ucCompilerFiles = new OR.Lazarus.Windows.UserControls.UCCompilerFiles();
            this.mLog = new OR.Lazarus.Windows.CompilerLogViewer();
            this.menuStrip1 = new System.Windows.Forms.MenuStrip();
            this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.settingsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator();
            this.exitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.compilerToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.goToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator();
            this.saveLogToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.toolStrip1 = new System.Windows.Forms.ToolStrip();
            this.btnCompile = new System.Windows.Forms.ToolStripButton();
            this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
            this.btnSaveLog = new System.Windows.Forms.ToolStripButton();
            this.toolStripContainer1.BottomToolStripPanel.SuspendLayout();
            this.toolStripContainer1.ContentPanel.SuspendLayout();
            this.toolStripContainer1.TopToolStripPanel.SuspendLayout();
            this.toolStripContainer1.SuspendLayout();
            this.statusStrip1.SuspendLayout();
            this.splitContainer1.Panel1.SuspendLayout();
            this.splitContainer1.Panel2.SuspendLayout();
            this.splitContainer1.SuspendLayout();
            this.menuStrip1.SuspendLayout();
            this.toolStrip1.SuspendLayout();
            this.SuspendLayout();
            // 
            // toolStripContainer1
            // 
            // 
            // toolStripContainer1.BottomToolStripPanel
            // 
            this.toolStripContainer1.BottomToolStripPanel.Controls.Add(this.statusStrip1);
            // 
            // toolStripContainer1.ContentPanel
            // 
            this.toolStripContainer1.ContentPanel.Controls.Add(this.splitContainer1);
            this.toolStripContainer1.ContentPanel.Size = new System.Drawing.Size(692, 395);
            this.toolStripContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
            this.toolStripContainer1.LeftToolStripPanelVisible = false;
            this.toolStripContainer1.Location = new System.Drawing.Point(0, 0);
            this.toolStripContainer1.Name = "toolStripContainer1";
            this.toolStripContainer1.RightToolStripPanelVisible = false;
            this.toolStripContainer1.Size = new System.Drawing.Size(692, 466);
            this.toolStripContainer1.TabIndex = 4;
            this.toolStripContainer1.Text = "toolStripContainer1";
            // 
            // toolStripContainer1.TopToolStripPanel
            // 
            this.toolStripContainer1.TopToolStripPanel.Controls.Add(this.menuStrip1);
            this.toolStripContainer1.TopToolStripPanel.Controls.Add(this.toolStrip1);
            // 
            // statusStrip1
            // 
            this.statusStrip1.Dock = System.Windows.Forms.DockStyle.None;
            this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
            this.lblGenerationProgress,
            this.barGenerationProgress,
            this.lblStatus});
            this.statusStrip1.Location = new System.Drawing.Point(0, 0);
            this.statusStrip1.Name = "statusStrip1";
            this.statusStrip1.Size = new System.Drawing.Size(692, 22);
            this.statusStrip1.TabIndex = 6;
            this.statusStrip1.Text = "statusStrip1";
            // 
            // lblGenerationProgress
            // 
            this.lblGenerationProgress.Name = "lblGenerationProgress";
            this.lblGenerationProgress.Size = new System.Drawing.Size(133, 17);
            this.lblGenerationProgress.Text = "Files Generated: ( 0 / 0 ) ";
            // 
            // barGenerationProgress
            // 
            this.barGenerationProgress.Name = "barGenerationProgress";
            this.barGenerationProgress.Size = new System.Drawing.Size(100, 16);
            // 
            // lblStatus
            // 
            this.lblStatus.Name = "lblStatus";
            this.lblStatus.Size = new System.Drawing.Size(164, 17);
            this.lblStatus.Text = "Waiting to begin Compilation";
            // 
            // splitContainer1
            // 
            this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
            this.splitContainer1.FixedPanel = System.Windows.Forms.FixedPanel.Panel1;
            this.splitContainer1.Location = new System.Drawing.Point(0, 0);
            this.splitContainer1.Name = "splitContainer1";
            this.splitContainer1.Orientation = System.Windows.Forms.Orientation.Horizontal;
            // 
            // splitContainer1.Panel1
            // 
            this.splitContainer1.Panel1.Controls.Add(this.m_ucCompilerFiles);
            // 
            // splitContainer1.Panel2
            // 
            this.splitContainer1.Panel2.Controls.Add(this.mLog);
            this.splitContainer1.Size = new System.Drawing.Size(692, 395);
            this.splitContainer1.SplitterDistance = 77;
            this.splitContainer1.TabIndex = 6;
            this.splitContainer1.Text = "splitContainer1";
            // 
            // m_ucCompilerFiles
            // 
            this.m_ucCompilerFiles.ConfigFile = "";
            this.m_ucCompilerFiles.Dock = System.Windows.Forms.DockStyle.Top;
            this.m_ucCompilerFiles.Location = new System.Drawing.Point(0, 0);
            logDetail1.Name = null;
            logDetail1.ParentCollection = null;
            logDetail1.ParentEntity = null;
            this.m_ucCompilerFiles.Log = logDetail1;
            this.m_ucCompilerFiles.Name = "m_ucCompilerFiles";
            this.m_ucCompilerFiles.Size = new System.Drawing.Size(692, 64);
            this.m_ucCompilerFiles.SourceFile = "";
            this.m_ucCompilerFiles.TabIndex = 6;
            // 
            // mLog
            // 
            this.mLog.Dock = System.Windows.Forms.DockStyle.Fill;
            this.mLog.Font = new System.Drawing.Font("Tahoma", 8F);
            this.mLog.Location = new System.Drawing.Point(0, 0);
            this.mLog.Name = "mLog";
            this.mLog.ReadOnly = true;
            this.mLog.Size = new System.Drawing.Size(692, 314);
            this.mLog.TabIndex = 4;
            this.mLog.Text = "";
            this.mLog.WordWrap = false;
            this.mLog.LinkClicked += new System.Windows.Forms.LinkClickedEventHandler(this.mLog_LinkClicked);
            // 
            // menuStrip1
            // 
            this.menuStrip1.Dock = System.Windows.Forms.DockStyle.None;
            this.menuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
            this.fileToolStripMenuItem,
            this.compilerToolStripMenuItem});
            this.menuStrip1.Location = new System.Drawing.Point(0, 0);
            this.menuStrip1.Name = "menuStrip1";
            this.menuStrip1.Size = new System.Drawing.Size(692, 24);
            this.menuStrip1.TabIndex = 1;
            this.menuStrip1.Text = "menuStrip1";
            // 
            // fileToolStripMenuItem
            // 
            this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
            this.settingsToolStripMenuItem,
            this.toolStripSeparator2,
            this.exitToolStripMenuItem});
            this.fileToolStripMenuItem.Name = "fileToolStripMenuItem";
            this.fileToolStripMenuItem.Size = new System.Drawing.Size(37, 20);
            this.fileToolStripMenuItem.Text = "&File";
            // 
            // settingsToolStripMenuItem
            // 
            this.settingsToolStripMenuItem.Name = "settingsToolStripMenuItem";
            this.settingsToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
            this.settingsToolStripMenuItem.Text = "&Settings";
            this.settingsToolStripMenuItem.Click += new System.EventHandler(this.DoSetPaths);
            // 
            // toolStripSeparator2
            // 
            this.toolStripSeparator2.Name = "toolStripSeparator2";
            this.toolStripSeparator2.Size = new System.Drawing.Size(149, 6);
            // 
            // exitToolStripMenuItem
            // 
            this.exitToolStripMenuItem.Name = "exitToolStripMenuItem";
            this.exitToolStripMenuItem.ShortcutKeyDisplayString = "Alt-F4";
            this.exitToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Alt | System.Windows.Forms.Keys.F4)));
            this.exitToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
            this.exitToolStripMenuItem.Text = "E&xit";
            this.exitToolStripMenuItem.Click += new System.EventHandler(this.DoExit);
            // 
            // compilerToolStripMenuItem
            // 
            this.compilerToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
            this.goToolStripMenuItem,
            this.toolStripSeparator3,
            this.saveLogToolStripMenuItem});
            this.compilerToolStripMenuItem.Name = "compilerToolStripMenuItem";
            this.compilerToolStripMenuItem.Size = new System.Drawing.Size(68, 20);
            this.compilerToolStripMenuItem.Text = "&Compiler";
            // 
            // goToolStripMenuItem
            // 
            this.goToolStripMenuItem.Name = "goToolStripMenuItem";
            this.goToolStripMenuItem.ShortcutKeyDisplayString = "F5";
            this.goToolStripMenuItem.ShortcutKeys = System.Windows.Forms.Keys.F5;
            this.goToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
            this.goToolStripMenuItem.Text = "&Go";
            this.goToolStripMenuItem.Click += new System.EventHandler(this.DoCompile);
            // 
            // toolStripSeparator3
            // 
            this.toolStripSeparator3.Name = "toolStripSeparator3";
            this.toolStripSeparator3.Size = new System.Drawing.Size(149, 6);
            // 
            // saveLogToolStripMenuItem
            // 
            this.saveLogToolStripMenuItem.Name = "saveLogToolStripMenuItem";
            this.saveLogToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
            this.saveLogToolStripMenuItem.Text = "&Save Log";
            this.saveLogToolStripMenuItem.Click += new System.EventHandler(this.DoSaveLog);
            // 
            // toolStrip1
            // 
            this.toolStrip1.Dock = System.Windows.Forms.DockStyle.None;
            this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
            this.btnCompile,
            this.toolStripSeparator1,
            this.btnSaveLog});
            this.toolStrip1.Location = new System.Drawing.Point(3, 24);
            this.toolStrip1.Name = "toolStrip1";
            this.toolStrip1.Size = new System.Drawing.Size(164, 25);
            this.toolStrip1.TabIndex = 0;
            this.toolStrip1.Text = "toolStrip1";
            // 
            // btnCompile
            // 
            this.btnCompile.Image = ((System.Drawing.Image)(resources.GetObject("btnCompile.Image")));
            this.btnCompile.ImageTransparentColor = System.Drawing.Color.Magenta;
            this.btnCompile.Name = "btnCompile";
            this.btnCompile.Size = new System.Drawing.Size(72, 22);
            this.btnCompile.Text = "Compile";
            this.btnCompile.ToolTipText = "Compile Source Document (F5)";
            this.btnCompile.Click += new System.EventHandler(this.DoCompile);
            // 
            // toolStripSeparator1
            // 
            this.toolStripSeparator1.Name = "toolStripSeparator1";
            this.toolStripSeparator1.Size = new System.Drawing.Size(6, 25);
            // 
            // btnSaveLog
            // 
            this.btnSaveLog.Image = ((System.Drawing.Image)(resources.GetObject("btnSaveLog.Image")));
            this.btnSaveLog.ImageTransparentColor = System.Drawing.Color.Magenta;
            this.btnSaveLog.Name = "btnSaveLog";
            this.btnSaveLog.Size = new System.Drawing.Size(74, 22);
            this.btnSaveLog.Text = "Save Log";
            this.btnSaveLog.ToolTipText = "Save Compiler Log to File";
            this.btnSaveLog.Click += new System.EventHandler(this.DoSaveLog);
            // 
            // Form1
            // 
            this.ClientSize = new System.Drawing.Size(692, 466);
            this.Controls.Add(this.toolStripContainer1);
            this.Font = new System.Drawing.Font("Tahoma", 8F);
            this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
            this.MainMenuStrip = this.menuStrip1;
            this.Name = "Form1";
            this.Text = "RCS Lazarus 4 - Compiler";
            this.Closing += new System.ComponentModel.CancelEventHandler(this.Form1_Closing);
            this.toolStripContainer1.BottomToolStripPanel.ResumeLayout(false);
            this.toolStripContainer1.BottomToolStripPanel.PerformLayout();
            this.toolStripContainer1.ContentPanel.ResumeLayout(false);
            this.toolStripContainer1.TopToolStripPanel.ResumeLayout(false);
            this.toolStripContainer1.TopToolStripPanel.PerformLayout();
            this.toolStripContainer1.ResumeLayout(false);
            this.toolStripContainer1.PerformLayout();
            this.statusStrip1.ResumeLayout(false);
            this.statusStrip1.PerformLayout();
            this.splitContainer1.Panel1.ResumeLayout(false);
            this.splitContainer1.Panel2.ResumeLayout(false);
            this.splitContainer1.ResumeLayout(false);
            this.menuStrip1.ResumeLayout(false);
            this.menuStrip1.PerformLayout();
            this.toolStrip1.ResumeLayout(false);
            this.toolStrip1.PerformLayout();
            this.ResumeLayout(false);

		}
		#endregion

		/// <summary>
		/// The main entry point for the application.
		/// </summary>
		[STAThread]
		static void Main() 
		{
			Application.Run( new Form1() );
		}

		protected virtual void OnInitializeConfigSelector()
		{
			
		}

        protected override void OnShown(EventArgs e)
        {
            LazarusConfig.Load();

            base.OnShown(e);
        }

        protected virtual void OnInit()
		{
			LazarusConfig.Initialize();
			LazarusConfig.Load();

			LazarusConfig.LogViewerManager.Items.Add( this );
			LazarusConfig.LogViewerManager.Items.Add( mLog );

			this.InitializeFormTitle();
			this.InitializePersistence();
		}

		protected virtual void InitializeFormTitle()
		{
			this.Text = String.Format( "RCS Lazarus 4 - Compiler ( v{0} )", Application.ProductVersion );
		}

		protected virtual bool InitializeManagers()
		{
			bool vReturn = false;

			try
			{
				CompilerEngineFactory vEngineFactory = new CompilerEngineFactory();
				mCompiler = vEngineFactory.CreateEngine( m_ucCompilerFiles.ConfigFile );
			}
			catch ( Exception ex )
			{
				LazarusConfig.LogViewerManager.AddError( ex );

				return ( vReturn );
			}

			//mCompiler = new CompilerEngine< Source.ProjectDetail, Compiled.ProjectDetail, SourceValidator, SourceCompiler, SourceGenerator >();

			mCompiler.Initialize();

			vReturn = true;

			return ( vReturn );
		}

		protected virtual void OnSetPaths()
		{
			LazarusSettings	v_oSettings	= new LazarusSettings();

			v_oSettings.ShowDialog();
		}

		protected virtual void OnSavePaths()
		{
         if ( !DataUtility.IsEmpty( m_ucCompilerFiles.ConfigFile ) )
         {
            LazarusConfig.ConfigPath = Path.GetDirectoryName( m_ucCompilerFiles.ConfigFile );
         }

         if ( !DataUtility.IsEmpty( m_ucCompilerFiles.SourceFile ) )
         {
            LazarusConfig.SourcePath = Path.GetDirectoryName( m_ucCompilerFiles.SourceFile );
         }

			LazarusConfig.Save();
		}

		protected virtual void InitializePersistence()
		{
			NameTable v_oNames = new NameTable();

			PersistenceConfig.Namespaces = new XmlNamespaceManager( v_oNames );
			PersistenceConfig.Namespaces.AddNamespace( "lz", "http://schemas.icitadel.com/Lazarus/Source.xsd" );
			PersistenceConfig.Namespaces.AddNamespace( "lzc", "http://schemas.icitadel.com/Lazarus/Compiled.xsd" );
			PersistenceConfig.Namespaces.AddNamespace( "lcfg", "http://schemas.icitadel.com/Lazarus/Config.xsd" );
			PersistenceConfig.Namespaces.AddNamespace( "lcfs", "http://schemas.icitadel.com/Lazarus/ConfigList.xsd" );
		}

		protected virtual void OnCompile()
		{
			mLog.Clear();
			
			mLog.Enabled = false;

			if ( !this.InitializeManagers() )
			{
				return;
			}

			barGenerationProgress.Value = 0;
			lblGenerationProgress.Text = "Files Generated: ( 0 / 0 ) ";

			try
			{
				LazarusConfig.Validate();
			}
			catch ( Exception ex )
			{
				MessageBox.Show( this, ex.Message, "Path Configuration Error" );

				this.OnSetPaths();
			}

			try
			{
				mCompiler.Initialize( m_ucCompilerFiles.ConfigFile, m_ucCompilerFiles.SourceFile );

				mCompiler.Compile();
			}
			catch ( Exception ex )
			{
				LazarusConfig.LogViewerManager.AddError( ex );
			}
			finally
			{
				mLog.Enabled = true;

				this.OnSavePaths();
			}
		}

		private void DoCompile( object sender, System.EventArgs e )
		{
			this.OnCompile();
		}

		private void DoGenerateFile( object sender, GenerateEventArgs e )
		{
			lblGenerationProgress.Text = String.Format( "Files Generated: ( {0:n0} / {1:n0} ) ", mCompiler.FilesGenerated, mCompiler.FilesToGenerate );

		}

		private void Form1_Closing( object sender, System.ComponentModel.CancelEventArgs e )
		{
			LazarusConfig.Save();
		}

		private void mLog_LinkClicked( object sender, System.Windows.Forms.LinkClickedEventArgs e )
		{
			string v_szUri;

			v_szUri = e.LinkText.Replace( "%20d", " " );

			Process.Start( v_szUri );
		}

		private void DoSetPaths( object sender, System.EventArgs e )
		{
			this.OnSetPaths();
		}

		private void m_txtLog_LinkClicked( object sender, LinkClickedEventArgs e )
		{

		}

		private void DoSaveLog( object sender, EventArgs e )
		{
			SaveFileDialog vDialog = new SaveFileDialog();
			
			vDialog.Filter = "txt files (*.txt)|*.txt";
			vDialog.InitialDirectory = LazarusConfig.OutputPath;

			if ( vDialog.ShowDialog() == DialogResult.OK )
			{
				FileUtility.WriteFile( vDialog.FileName, mLog.Text );
			}
		}

		private void DoExit( object sender, EventArgs e )
		{
			this.OnSavePaths();

			this.Close();
		}

		#region ILogViewer Members

		public void AddMessage( Color pColor, string pMessage )
		{
            if (mCompiler != null)
            {
                barGenerationProgress.Minimum = 0;
                barGenerationProgress.Maximum = mCompiler.FilesToGenerate;
                barGenerationProgress.Value = mCompiler.FilesGenerated;

                lblGenerationProgress.Text = "Files Generated: ( " + mCompiler.FilesGenerated.ToString() + " / " + mCompiler.FilesToGenerate.ToString() + " )";
            }

			lblStatus.Text = pMessage;

			Application.DoEvents();
		}

		public void AddLineBreak()
		{
		}

		#endregion
	}
}
